package com.xingda.packing.dmss.shunt.handle;

import com.xingda.packing.dmss.common.ScanCodeUtils;
import com.xingda.packing.dmss.domain.ProductBoxLocation;
import com.xingda.packing.dmss.domain.ShuntProductionLine;
import com.xingda.packing.dmss.domain.Wheel;
import com.xingda.packing.dmss.enums.*;
import com.xingda.packing.dmss.events.EventCreater;
import com.xingda.packing.dmss.http.WheelHttp;
import com.xingda.packing.dmss.rule.RuleUtilsV2;
import com.xingda.packing.dmss.shunt.ticket.ShuntTicket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Component
public class ShuntHandle implements TaskHandleService {
    @Resource
    RuleUtilsV2 ruleUtils;
    @Resource
    EventCreater eventCreater;

    @Override
    public boolean accept(ShuntProductionLine productionLine) {
        return checkTask(productionLine.getTaskTicket(), TaskType.SHUNT);
    }

    @Override
    public void process(ShuntProductionLine productionLine) {
        ShuntTicket taskTicket = (ShuntTicket) productionLine.getTaskTicket();
        Wheel wheel = taskTicket.getWheel();
        if (productionLine.getCodeErrorNum() == 3) {
            productionLine.stopTask();
            eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_CODE_ERROR_MORE_THAN_THREE, true, 3);
            productionLine.createAlarmEvent("条码拍照错误三次,已停止任务");
            return;
        }
        if (productionLine.getSnapErrorNum() == 3) {
            productionLine.stopTask();
            eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_SNAP_ERROR_MORE_THAN_THREE, true, 3);
            productionLine.createAlarmEvent("卡扣识别错误三次,已停止任务");
            return;
        }
        String scanWheelNo = "";
        if (productionLine.isSnapSignal() || productionLine.isScanSignal()) {
            scanWheelNo = productionLine.getScanWheelNo();
            log.info("_______________视觉拍照信息 :{}", scanWheelNo);
            scanWheelNo = productionLine.getScanWheelNo();
            log.info("_______________视觉拍照信息 :{}", scanWheelNo);
            //过滤指令回复信息
            if (scanWheelNo.startsWith("000027")) {
                return;
            }
            //保存视觉信息
            productionLine.saveVisualSense(scanWheelNo, 3);
        }

        //条码空信息直接返回
        if (!StringUtils.hasText(scanWheelNo)) {
            if (productionLine.isScanSignal()) {
                productionLine.codeParsingFailed();
                productionLine.createAlarmEvent("条码数据为空");
                productionLine.setCodeErrorNum(productionLine.getCodeErrorNum() + 1);
                return;
            }
            if (productionLine.isSnapSignal()) {
                productionLine.snapParsingFailed();
                productionLine.createAlarmEvent("卡扣数据为空");
                productionLine.setSnapErrorNum(productionLine.getSnapErrorNum() + 1);
                return;
            }
        }
        //检测条码颜色
        if (wheel == null) {
            int productType = productionLine.getProductType();
            if (scanWheelNo.startsWith("000070")) {
                String code = ScanCodeUtils.scanCodeToBarCodeAndColor(scanWheelNo);
                log.info("解析出条码是{}", code);
                String wheelNo = code.split("_")[0];
                log.info("解析出轮号是{}", wheelNo);
                String color = code.split("_")[1];
                log.info("解析出颜色是{}", color);
                //颜色未识别 条码识别
                if (color.equals("Z") || wheelNo.startsWith("#")) {
                    productionLine.createAlarmEvent("颜色||条码未解析成功,code:" + code);
                    productionLine.setCodeErrorNum(productionLine.getCodeErrorNum() + 1);
                    productionLine.codeParsingFailed();
                    return;
                }

                //识别正常
                wheel = WheelHttp.queryIntermediateVO(wheelNo, productType);
                if (wheel.getVFree2().equals("B80") && color.equals("D")) {
                    //B80识别为粉色的 改判为红
                    color = "A";
                }
                if (wheel.getVFree2().equals("B40") && color.equals("A")) {
                    //B40识别为红色的 改判为粉
                    color = "D";
                }
                if (wheel.getVFree2().equals("B80/17") && color.equals("A")) {
                    //B80/17识别为红色的 改判为粉
                    color = "D";
                }
                if (wheel.getVFree2().equals("B60") && color.equals("D")) {
                    //B60识别为粉色的 改判为红
                    color = "A";
                }
                //工字轮高低位和PLC获取的高低位判断
                if (!isConsistent(wheel, productType)) {
                    productionLine.stopTask();
                    productionLine.createAlarmEvent("条码获取类型和PLC检测类型不一致");
                    eventCreater.createTriggerAlarm(AlarmTriggerType.PRODUCT_TYPE_ERROR, true, 3);
                    return;
                }
                if (wheel.getBarCode().startsWith("XC") && !wheel.isAvailable()) {
                    productionLine.stopTask();
                    eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_WHEEL_NO_AVAILABLE, true, 3);
                    productionLine.createAlarmEvent("工字轮条码为成品,查询信息为不合格品,已停止系统,工字轮条码:" + wheelNo);
                    return;
                }
                if (wheel.getState() == WheelUseState.PACK_BOX.getNumber()) {
                    productionLine.getPackProductionLine().getRobot().createAlarmEvent("工字轮已装箱,信息已上传,已停止系统,工字轮条码:" + wheel.getBarCode(), 3);
                    productionLine.stopTask();
                    return;
                }
                if (!productionLine.getPackProductionLine().getRobot().getTagValue(3)) {
                    productionLine.getPackProductionLine().getRobot().checkPackingStatus(3, wheel.getBarCode());
                }

                if (productionLine.getPackProductionLine().getRobot().getAlreadyPackingStatus(3)) {
                    productionLine.stopTask();
                    productionLine.getPackProductionLine().getRobot().createAlarmEvent("工字轮已装箱,已停止系统,工字轮条码:" + wheel.getBarCode(), 3);
                    return;
                }
                BigDecimal torsionValue = wheel.getTorsionValue();
                if (torsionValue.compareTo(BigDecimal.valueOf(999.0)) == 0 && Objects.isNull(wheel.getConsumerName())) {
                    // 停止 触发报警
                    productionLine.stopTask();
                    eventCreater.createTriggerAlarm(AlarmTriggerType.WHEEL_ERROR_999, true, 3);
                    productionLine.createAlarmEvent("网络错误,已停止任务,工字轮条码:" + wheelNo);
                    return;
                } else if (torsionValue.compareTo(BigDecimal.valueOf(9999.0)) == 0 && Objects.isNull(wheel.getConsumerName())) {
                    // 停止 触发
                    productionLine.stopTask();
                    eventCreater.createTriggerAlarm(AlarmTriggerType.WHEEL_ERROR_9999, true, 3);
                    productionLine.createAlarmEvent("条码信息为空,已停止任务,工字轮条码:" + wheelNo);
                    return;
                } else {
                    if (wheel.getBarCode().startsWith("XD")) {
                        //wheel.setWheelTag("NOT-" + productionLine.getPackProductionLine().getRobot().getInvNameByInvBasDoc(wheel.getPkInvbasdoc()) + "-" + wheel.getVFree2() + "-" + 10600);
                        wheel.setWheelTag("NOT-" + productionLine.getPackProductionLine().getRobot().getInvNameByInvBasDoc(wheel.getPkInvbasdoc()) + "-" + wheel.getVFree2() + "-" + wheel.getFixedLength());
                    } else {
                        //wheel.setWheelTag(productionLine.getPackProductionLine().getRobot().getInvNameByInvBasDoc(wheel.getPkInvbasdoc()) + "-" + wheel.getVFree2() + "-" + 10600 + "-" + WheelSurfaceType.getByAB(color).getGr());
                        wheel.setWheelTag(productionLine.getPackProductionLine().getRobot().getInvNameByInvBasDoc(wheel.getPkInvbasdoc()) + "-" + wheel.getVFree2() + "-" + wheel.getFixedLength() + "-" + WheelSurfaceType.getByAB(color).getGr());
                    }
                }
                if (wheelNo.length() == 13) {
                    wheelNo = wheelNo + "#####_" + color;
                }
                if (wheelNo.length() == 16) {
                    wheelNo = wheelNo + "##_" + color;
                }
                //wheel.setWheelTagMap(productionLine.getPackProductionLine().getRobot().getInvNameByInvBasDoc(wheel.getPkInvbasdoc()) + "-" + wheel.getVFree2() + "-" + 10600);
                wheel.setWheelTagMap(productionLine.getPackProductionLine().getRobot().getInvNameByInvBasDoc(wheel.getPkInvbasdoc()) + "-" + wheel.getVFree2() + "-" + wheel.getFixedLength());
                wheel.setBarCodeBack(wheelNo);
                wheel.setAb(color);
                productionLine.codeParsingSucceeded();
            } else {
                //条码检测失败
                productionLine.codeParsingFailed();
                productionLine.createAlarmEvent("条码检测失败");
                productionLine.setCodeErrorNum(productionLine.getCodeErrorNum() + 1);
                return;
            }
            taskTicket.setWheel(wheel);
            productionLine.saveTicket(taskTicket);
        }
        //检测卡扣信息
        if (!taskTicket.isFlag()) {
            if (scanWheelNo.startsWith("000070")) {
                return;
            }
            if (scanWheelNo.startsWith("000056")) {
                //卡扣检测成功
                productionLine.snapParsingSucceeded();
                taskTicket.setFlag(true);
                productionLine.saveTicket(taskTicket);
            } else {
                //卡扣检测失败
                productionLine.snapParsingFailed();
                productionLine.createAlarmEvent("卡扣检测失败");
                productionLine.setSnapErrorNum(productionLine.getSnapErrorNum() + 1);
                return;
            }
        }
        //判断转向
        List<ProductBoxLocation> allProductBoxLocation = productionLine.getAllProductBoxLocation();
        if (allProductBoxLocation.isEmpty()) {
            productionLine.createAlarmEvent("当前区域的装箱区为空");
            productionLine.stopTask();
            log.info("装箱区为空");
            return;
        }
        int location = taskTicket.getLocation();
        if (location == 0) {
            List<ProductBoxLocation> canShuntBoxLocation = new ArrayList<>();
            for (ProductBoxLocation productBoxLocation : allProductBoxLocation) {
                if (productBoxLocation.isEmpty()) {
                    continue;
                }
                if (ruleUtils.canShunt(productBoxLocation.getProductBox(), wheel)) {
                    canShuntBoxLocation.add(productBoxLocation);
                }
            }
            if (canShuntBoxLocation.size() == 1) {
                ProductBoxLocation productBoxLocation = canShuntBoxLocation.get(0);
                if (productBoxLocation.getLocationNo() > 6) {
                    location = 2;
                } else {
                    location = 1;
                }
            } else if (canShuntBoxLocation.size() > 1) {
                //判断符合的装箱是不是在同一个区域
                if (canShuntBoxLocation.size() == canShuntBoxLocation.stream().filter(ProductBoxLocation::isLeft).count() || canShuntBoxLocation.size() == canShuntBoxLocation.stream().filter(ProductBoxLocation::isRight).count()) {
                    if (canShuntBoxLocation.get(0).getLocationNo() > 6) {
                        location = 2;
                    } else {
                        location = 1;
                    }
                } else {
                    location = ruleUtils.randomShunt(wheel, canShuntBoxLocation);
                    if (location == 0) {
                        location = ruleUtils.randomShunt(productionLine);
                    }
                }
            }
            //都不符合 停机触发报警
            if (location == 0) {
                productionLine.stopTask();
                eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_WHEEL_NO_SHUNT, true, 3);
                productionLine.createAlarmEvent("当前工字轮不符合装箱,已停止分流区:" + wheel.getWheelTag() + "-客户:" + wheel.getConsumerName());
                return;
            }
            taskTicket.setLocation(location);
            productionLine.saveTicket(taskTicket);
        }
        if (productionLine.canShut(location)) {
            //分流
            productionLine.wheelToLeftOrRight(location, wheel.getBarCodeBack());
            log.info("分流区写入{}", ShuntAreaType.getByLocation(location));
            taskTicket.setState(TaskState.RUNING);
            taskTicket.setWheel(wheel);
            taskTicket.setLocation(location);
            //事件保存
            productionLine.handleShuntEvent(taskTicket);
        }
    }

    private boolean isConsistent(Wheel wheel, int productType) {
        if (wheel.getVFree2().startsWith("B80") && productType == 2) {
            return true;
        }
        return wheel.getVFree2().equals("B40") || wheel.getVFree2().equals("B60") && productType == 1;
    }
}
